package jddk;

import java.io.UnsupportedEncodingException;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;

public class DesUtil {

	// 偏移
	//private final static String IV_PARAMETER = "12345678";
	// 密钥算法
	private static final String ALGORITHM = "DES";
	// 加密/解密算法-工作模式-填充模式
	private static final String CIPHER_ALGORITHM = "DES/ECB/NoPadding";
	// 默认编码
	private static final String CHARSET = "GBK";

	private static Key generatekey(String password) throws Exception {
		DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));
		SecretKeyFactory ketFactory = SecretKeyFactory.getInstance(ALGORITHM);
		return ketFactory.generateSecret(dks);
		//return SecureUtil.generateKey(CIPHER_ALGORITHM, password.getBytes(CHARSET));
	}

	public static void main(String[] args) {
		/**/
		//SecretKey key = KeyUtil.generateDESKey(SymmetricAlgorithm.DES.getValue(), "12345678".getBytes());
		//System.out.println(key);
		//DES des = new DES(Mode.ECB, Padding.NoPadding, "12345678".getBytes());
		//byte[] bytea = decrypt(des.encrypt("guojian"), "12345678");
		//System.out.println(new String(bytea));
		//	SecureUtil.generateDESKey(CIPHER_ALGORITHM, "12345678".getBytes());
		//System.out.println(encrypt("123", IV_PARAMETER));

		/*byte[] dess = decrypt(encrypt("guojian11111", "12345678"), "12345678");
		System.out.println(new String(dess));*/
		//SM4 sm4 = new SM4("EYePZ0KkVwj0CfqP".getBytes());
		//System.out.println(sm4.encryptBase64("guojian"));

		try {

			String base64GBk = "ufq87A==";//gbk编码格式的数据

			byte[] des = Base64.decode(base64GBk.getBytes("GBK"));

			System.out.println(new String(des, "GBK"));

			System.out.println(Base64.encode("a"));

			//byte[] a = "国检".getBytes("");

			//String aa = new String(ByteUtils.subArray(a, 1, 2),Charset.defaultCharset());

			//System.out.println(new String(a));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		String base64utf_8 = "5Zu95qOA";
		System.out.println(Base64.decodeStr(base64utf_8));

		SecretKey key = SecureUtil.generateDESKey("DES", "12345678".getBytes());
		DES des = new DES(Mode.CBC, Padding.PKCS5Padding, key, new IvParameterSpec("12345678".getBytes()));
		System.out.println(des.encryptBase64("12345678"));//PXWVqYv/gJ1e7qlmi0f0pQ==
		System.out.println(des.decryptStr("PXWVqYv/gJ1e7qlmi0f0pQ=="));
		
	}

	// 报文加密
	public static byte[] encrypt(String data, String password) {
		if (password == null || password.length() < 8) {
			throw new RuntimeException("加密失败，key不能小于8位");
		}
		if (data == null) {
			return null;
		}
		try {
			int ys = data.getBytes(CHARSET).length % 8;
			if (ys != 0) {
				data = bin2hex(data);
				for (int i = 0; i < 8 - ys; i++) {
					data = data + "00";
				}
				data = formHex(data);
			}

			Key secretKey = generatekey(password);
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	// 报文解密
	public static byte[] decrypt(byte[] data, String password) {
		if (password == null || password.length() < 8) {
			throw new RuntimeException("加密失败，key不能小于8位");
		}
		if (data == null)
			return null;
		try {
			Key secretKey = generatekey(password);
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, secretKey);
			byte[] bytes = cipher.doFinal(data);
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private static int toDigit(char ch, int index) {
		int digit = Character.digit(ch, 16);
		if (digit == -1) {
			throw new RuntimeException("");
		}
		return digit;
	}

	// 16进制字符串转string
	public static String formHex(String hex) {
		hex = hex.replace("\\x", "");
		char[] data = hex.toCharArray();
		int len = data.length;
		if ((len & 0x01) != 0) {
			throw new RuntimeException("字符数应该为偶数");
		}
		byte[] out = new byte[len >> 1];
		for (int i = 0, j = 0; j < len; i++) {
			int f = toDigit(data[j], j) << 4;
			j++;
			f |= toDigit(data[j], j);
			j++;
			out[i] = (byte) (f & 0xFF);
		}
		return new String(out);
	}

	// 字符串转16进制
	public static String bin2hex(String bin) {
		char[] digital = "0123456789ABCDEF".toCharArray();
		StringBuffer sb = new StringBuffer("");
		byte[] bs = bin.getBytes();
		int bit;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(digital[bit]);
			bit = bs[i] & 0x0f;
			sb.append(digital[bit]);
		}
		return sb.toString();
	}

}
